#!/usr/bin/env python

###
# Wifi + GPS fingerprint collection tool
# Copyright (c) 2008, Yura Zenevich, Jorge Silva, and Jamon Camisso
# Homepage http://wiki.scyp.atrc.utoronto.ca/wiki/WiFiPositioning
# Contact scyp@atrc.utoronto.ca
#    
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program, see enclosed file gpl-3.txt or browse to
# <http://www.gnu.org/licenses/gpl.txt>
###

from numpy import *
from numpy.linalg import lstsq

#	Estimate current location using newVector as current fingerprint,
#	betax and betay estimations.
def Estimate(newVector, betax, betay):

	return dot(newVector, betax), dot(newVector, betay)

#	Get the esimation of betax and betay, which are estimation of our
#	transformation matrix.
def GetEstimators(xTx, xTvX, xTvY):

	return lstsq(xTx, xTvX)[0], lstsq(xTx, xTvY)[0]

#	Calculate estimated variance for out estimators.
def SSqEst(xVector, yVector, betax, betay, xMatrixTranspose, xTvX, xTvY, \
	newVector):
	
	return GetMse(xVector, betax, xMatrixTranspose) * (1 + \
		lstsq(betax, xTvX)[0] * dot(newVector.T, newVector))[0, 0], \
		GetMse(yVector, betay, xMatrixTranspose) * (1 + lstsq(betay, \
		xTvY)[0] * dot(newVector.T, newVector))[0, 0]

#	Get MSE - mean square error, which is an estimator for the variance of
#	our variable of interest.
def GetMse(vector, beta, xMatrixT):
	
	return fabs((dot(vector.T, vector)[0, 0] - dot(dot(beta.T, xMatrixT), \
		vector)[0, 0]) / (len(vector) - len(xMatrixT)))

#	Get the weight of the estimator based on it's relative variability to
#	another estimator.
def FindWeight(mse1, mse2):
	
	w1 = mse2 / (mse1 + mse2)

	return w1, 1 - w1

#	Build a correct vector for the fingerprint of out current location.
def GetNewVector(absolutifiedNewSearch):

	vector = []	
	vector.append(1)

	for mac, order in absolutifiedNewSearch[2]:
		vector.append(order)

	return array(vector)

#	Get the vector of all y or x coordinates (existing variables of 
#	interest), which is used to estimate a new x or y coordinate.
def GetVector(absolutifiedVectors, i):
	
	vector = []

	for av in absolutifiedVectors:
		row = []
		row.append(av[1][i])
		vector.append(row)

	return array(vector)

#	Build a matrix X for existing fingerprints used to obtain a 
#	transformation matrix (i.e. betax or betay).
def GetXMatrix(absolutifiedVectors):
	
	xMatrix = []
	
	for av in absolutifiedVectors:
		row = []
		row.append(1)
		for mac, order in av[2]:
			row.append(order)
		xMatrix.append(row)

	return array(xMatrix)
